﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Data.Entity;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;

namespace EntityFrameworkStudy.Studys
{
    #region 模型

    public class Article
    {
        public int Id { get; set; }

        public string Title { get; set; }
    }

    public class Post
    {
        public int Id { get; set; }

        public string Body { get; set; }

        public virtual int ArticleId { get; set; }

        public virtual Article Article { get; set; }
    }

    public class Catalog
    {
        public int Id { get; set; }

        public string Title { get; set; }
    }

    public class Book
    {
        public int Id { get; set; }

        public string Body { get; set; }

        public int? CatalogId { get; set; }

        public virtual Catalog Catalog { get; set; }
    }

    public class NewsType
    {
        public int Id { get; set; }

        public string Title { get; set; }
    }

    public class News
    {
        public int Id { get; set; }

        public string Body { get; set; }

        public int NewsTypeId { get; set; }

        public virtual NewsType NewsType { get; set; }
    }

    public class User
    {
        public int Id { get; set; }

        public string Title { get; set; }
    }

    public class Order
    {
        public int Id { get; set; }

        public string Product { get; set; }
    }

    public class Level1
    {
        public virtual int Level1Id { get; set; }

        public virtual ICollection<Level2> Level2s { get; set; }
    }

    public class Level2
    {
        public virtual int Level2Id { get; set; }
        public virtual int Level1Id { get; set; }

        public virtual ICollection<Level3> Level3s { get; set; }
    }

    public class Level3
    {
        public virtual int Level3Id { get; set; }
        public virtual int Level2Id { get; set; }
        public virtual int Level1Id { get; set; }
    }

    #endregion

    # region 数据上下文

    public class StudyContext : DbContext
    {
        public StudyContext() : base() { }

        public StudyContext(string nameOrConnectionString) : base(nameOrConnectionString) { }

        public DbSet<Article> Articles
        {
            get
            {
                return this.Set<Article>();
            }
        }

        public DbSet<Post> Posts
        {
            get
            {
                return this.Set<Post>();
            }
        }

        public DbSet<Catalog> Catalogs
        {
            get
            {
                return this.Set<Catalog>();
            }
        }

        public DbSet<Book> Books
        {
            get
            {
                return this.Set<Book>();
            }
        }

        public DbSet<NewsType> NewsTypes
        {
            get
            {
                return this.Set<NewsType>();
            }
        }

        public DbSet<News> News
        {
            get
            {
                return this.Set<News>();
            }
        }

        public DbSet<User> Users
        {
            get
            {
                return this.Set<User>();
            }
        }

        public DbSet<Order> Orders
        {
            get
            {
                return this.Set<Order>();
            }
        }

        public DbSet<Level1> Level1s
        {
            get
            {
                return this.Set<Level1>();
            }
        }

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            base.OnModelCreating(modelBuilder);

            modelBuilder.Entity<News>()
                .HasRequired(x => x.NewsType)
                .WithMany()
                .HasForeignKey(x => x.NewsTypeId)
                .WillCascadeOnDelete(false);


            modelBuilder.Entity<Order>()
                .HasKey(x => x.Id)
                .Property(x => x.Id)
                .HasDatabaseGeneratedOption(DatabaseGeneratedOption.None);

            modelBuilder.Entity<Level1>()
                .HasKey(x => x.Level1Id)
                .Property(x => x.Level1Id)
                .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
            modelBuilder.Entity<Level1>()
                .HasMany(x => x.Level2s)
                .WithRequired()
                .HasForeignKey(x => x.Level1Id)
                .WillCascadeOnDelete();

            modelBuilder.Entity<Level2>()
                .HasKey(x => new { x.Level2Id, x.Level1Id })
                .Property(x => x.Level2Id)
                .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
            modelBuilder.Entity<Level2>()
                .HasMany(x => x.Level3s)
                .WithRequired()
                .HasForeignKey(x => new { x.Level2Id, x.Level1Id })
                .WillCascadeOnDelete();

            modelBuilder.Entity<Level3>()
                .HasKey(x => new { x.Level3Id, x.Level2Id, x.Level1Id })
                .Property(x => x.Level3Id)
                .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
        }
    }

    #endregion
}
